#ifndef N1APPLICATIONSINGLETON_H_2006_07_02
#define N1APPLICATIONSINGLETON_H_2006_07_02

#include "N1Lib.h"
#include <stdlib.h>

/**********************************************************************
//How to use: 
class N1Some : public N1ApplicationSingleton<N1Some> {
public:
...
};
**********************************************************************/

template <class T>
class N1ApplicationSingleton {
private:
    typedef T MemberSingletonClass;

    static T* SetInstance(T* ptr) {
        char value[32 + N1BufferSizeForDecimalPointer];
        sprintf(value, "%s=%d", ptr->name(), ptr);
        //SetEnvironmentVariable(ptr->name(), value);
        //putenv(value);
        return ptr;
    }

    static T* FindInstance() {
        char * value = getenv( ptr->name() );
        if(!value) return NULL;
        return (T*)atoi(value);
    }

protected:
    N1ApplicationSingleton() { };
    virtual ~N1ApplicationSingleton() { };

public:
    static T* GetInstance() 
    {
        return FindInstance();
    }

    static T* Instance() 
    {
        T *ret = FindInstance();
        if(!ret) ret = SetInstance(new T());
        return ret;
    }

    template <class Param1>
    static T* Instance(Param1 p1) 
    {
        T *ret = FindInstance();
        if(!ret) ret = SetInstance(new T(Param1 p1));
        return ret;
    }

    template <class Param1, class Param2>
    static T* Instance(Param1 p1, Param2 p2) 
    {
        T *ret = FindInstance();
        if(!ret) ret = new SetInstance(T(Param1 p1, Param2 p2));
        return ret;
    }
};

#endif //N1APPLICATIONSINGLETON_H_2006_07_02
